#include "assist.h"
#include <time.h>
#include <string>

void conv2(unsigned char *image, int height, int width, int kernel[][3], float * res) {
	
	for (int row = 0; row < height + 2; row++) {
		for (int col = 0; col < width + 2; col++) {
			float accumulation = 0;
			for (int i = -1; i <= 1; i++) {
				for (int j = -1; j <= 1; j++) {
					unsigned char k;
					if ((row+i) < 0 || (col+j) < 0) k = 0;
					else k = image[(row + i) * width + (col + j)];
					accumulation += k * kernel[1+i][1+j];				
				}
			}
			res[row * (width + 2) + col] = accumulation;
		}		
	}	
}

void create_gradient_image(const char *filename) {
	
	unsigned char *origImg;
	int w, h;
	origImg = read_gray_image(filename, &w, &h); 
	IplImage* input = cvLoadImage(filename , 0);

	int kernel1[][3] = { { 1,  2,  1}, { 0,  0,  0}, {-1, -2, -1} };
	int kernel2[][3] = { { 1,  0, -1}, { 2,  0, -2}, { 1,  0, -1} };

	float *h1, *h2;
	h1 = new float[(h + 2) * (w + 2)];
	h2 = new float[(h + 2) * (w + 2)];

	conv2(origImg, h, w, kernel1, h1);
	conv2(origImg, h, w, kernel2, h2);

	IplImage *img = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
	
	float temp;

	int k = 0;
	
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w ; j++) {
		//	if (i == 0 || j == 0 || i == (h + 1) || j == (w + 1)) continue;
			float interm = sqrt(pow(h1[(i+1)*(w + 2)+(j+1)], 2) + pow(h2[(i+1)*(w + 2)+(j+1)], 2));
			if (interm > 255) temp = 255;
			else if (interm < 0) temp = 0;
			else temp = interm;

			(img->imageData + i*img->widthStep)[j] = temp;
			k++;
		}
	}
	//cvSaveImage("gradient.jpg", img);
	cvSaveImage("gradient.png", img);

	delete [] h1;
	delete [] h2;
}

void run_ift(int *mouse_position, int press_time, const char* filename) {
	
	cout << "Begin IFT" << endl;
	clock_t tic = clock(), toc;
	
	int w;
	int h;

	unsigned char * image;
	//image = read_gray_image("gradient.jpg" , &w , &h);
	image = read_gray_image("gradient.png" , &w , &h);

	int dim1 = h;
    int dim2 = w; 

	pixel_array My_image(image, dim1, dim2, mouse_position, press_time);

    int co = My_image.min_pixel();
	char output[100];
	
	while (!My_image.IslistEmpty()) {

		int c_x = co/dim2;
		int c_y = co%dim2;

		My_image.connection(c_x  , c_y - 1 , c_x , c_y);
		My_image.connection(c_x + 1 , c_y  , c_x , c_y);
		My_image.connection(c_x , c_y + 1 , c_x , c_y);
		My_image.connection(c_x - 1 , c_y  , c_x , c_y);

		co = My_image.min_pixel();
	}

	IplImage* gray_image = cvLoadImage(filename, 0);

    My_image.result_show(gray_image);
	
    //cvSaveImage("output.jpg", gray_image);
	cvSaveImage("output.png", gray_image);
	cvReleaseImage(&gray_image);

	toc = clock();
	cout << "IFT Finished" << endl;
	cout << "Total time elapsed: " << float(toc - tic)/1000 << " seconds" << endl;

}

void jpg2png(const char* filename) {
	IplImage* gray_image = cvLoadImage(filename, 0);
	string temp = filename;
	temp = temp.substr(0, temp.find_last_of("."));
	temp = temp + ".png";
	cvSaveImage(temp.c_str(), gray_image);
	cvReleaseImage(&gray_image);
}
